<template>
    <div>
        <h4>- Reflect：为了操作对象而提供的新 API，设计目的：</h4>
        <ul>
            <li>将Object对象的一些明显属于语言内部的方法（比如Object.defineProperty），放到Reflect对象上。</li>
            <li>修改某些Object方法的返回结果，让其变得更合理。比如，Object.defineProperty(obj, name, desc)在无法定义属性时，会抛出一个错误，而Reflect.defineProperty(obj, name, desc)则会返回false。</li>
            <li>让Object操作都变成函数行为。某些Object操作是命令式，比如name in obj和delete obj[name]，而Reflect.has(obj, name)和Reflect.deleteProperty(obj, name)让它们变成了函数行为</li>
            <li>Reflect对象的方法与Proxy对象的方法一一对应，只要是Proxy对象的方法，就能在Reflect对象上找到对应的方法，可以在Proxy内部调用Reflect方法，保证原生行为能够正常执行<code>new Proxy(obj, {get(target, name) {return Reflect.get(target, name);}})</code></li>
        </ul>
        <h4>- 静态方法</h4>
        <ul>
            <li><b>get(target, name, receiver)</b> 查找并返回target对象的name属性，如果没有该属性，则返回undefined。如果name属性部署了读取函数（getter），则读取函数的this绑定receiver</li>
            <li><b>set(target, name, value, receiver)</b> 设置target对象的name属性等于value。如果name属性设置了赋值函数，则赋值函数的this绑定receiver。</li>
            <li><b>apply(func, thisArg, args)</b> 等同于Function.prototype.apply.call(func, thisArg, args)，用于绑定this对象后执行给定函数</li>
            <li><b>has(obj, name) </b>对应name in obj里面的in运算符</li>
            <li><b>construct(target, args) </b>等同于new target(...args)，这提供了一种不使用new，来调用构造函数的方法。</li>
            <li><b>deleteProperty(obj, name) </b>同于delete obj[name]，用于删除对象的属性。方法返回一个布尔值</li>
            <li><b>defineProperty(target, propertyKey, attributes) </b>等同于Object.defineProperty，用来为对象定义属性。未来，后者会被逐渐废除，请从现在开始就使用Reflect.defineProperty代替它</li>
            <li><b>getOwnPropertyDescriptor(target, propertyKey) </b>等同于Object.getOwnPropertyDescriptor，用于得到指定属性的描述对象，将来会替代掉后者。Reflect.getOwnPropertyDescriptor和Object.getOwnPropertyDescriptor的一个区别是，如果第一个参数不是对象，Object.getOwnPropertyDescriptor(1, 'foo')不报错，返回undefined，而Reflect.getOwnPropertyDescriptor(1, 'foo')会抛出错误，表示参数非法。</li>
            <li><b>getPrototypeOf(obj) </b>用于读取对象的__proto__属性，对应Object.getPrototypeOf(obj)；Reflect.getPrototypeOf和Object.getPrototypeOf的一个区别是，如果参数不是对象，Object.getPrototypeOf会将这个参数转为对象，然后再运行，而Reflect.getPrototypeOf会报错。</li>
            <li><b>isExtensible(target) </b>对应Object.isExtensible，返回一个布尔值，表示当前对象是否可扩展。如果参数不是对象，Object.isExtensible会返回false，因为非对象本来就是不可扩展的，而Reflect.isExtensible会报错</li>
            <li><b>ownKeys(target) </b>用于返回对象的所有属性，基本等同于Object.getOwnPropertyNames与Object.getOwnPropertySymbols之和。</li>
            <li><b>preventExtensions(target) </b>对应Object.preventExtensions方法，用于让一个对象变为不可扩展。它返回一个布尔值，表示是否操作成功。如果参数不是对象，Object.preventExtensions在 ES5 环境报错，在 ES6 环境返回传入的参数，而Reflect.preventExtensions会报错。</li>
            <li><b>setPrototypeOf(obj, newProto) </b>用于设置目标对象的原型（prototype），对应Object.setPrototypeOf(obj, newProto)方法。它返回一个布尔值，表示是否设置成功。</li>
        </ul>
        <h4>- 使用 Proxy 实现观察者模式</h4>
    </div>
</template>

<script>
export default {
    mounted() {
        let preObj = {}
        let proxy = new Proxy(preObj, {
            get: (target, propKey) => {
                return 35
            },
            set: (target, propKey, value) => {
                target[propKey] = value + 'b'
                return true
            }
        })
        proxy.demo = 'a'
        console.log(proxy.demo)
        console.log(preObj.demo)
    },
}
</script>

<style scoped>

</style>